5-2 }x}xs韃

對於一個只包含實數的稀疏矩陣,假設其維度為 m×n,含有 nnz 個非零元素,MATLAB 動用了三個內部陣列來儲存此稀疏矩陣的相關資訊:

因此,整個稀疏矩陣內存空間大小為 8*nnz + 8*nnz + 8*n + 8 = 16*nnz + 8*n + 8,多出來的 8 個 bytes 是用來儲存其他經常性資訊。以 MATLAB 的 west0479.mat 檔案為例,此檔案包含一個 479×479 的稀疏矩陣,我們可以驗證上述內存空間公式如下:

Example 1: 05-稀疏矩陣/memorySize01.mclear all load west0479.mat [m,n]=size(west0479); totalSize=16*nnz(west0479)+8*n+8 whos west0479totalSize = 34032 Name Size Bytes Class Attributes west0479 479x479 34032 double sparse

由上例可知,我們由上述內存空間公式所得到的結果,和 whos 指令所得到的結果是一致的。此外在上例中,nnz(west0479) 可傳回稀疏矩陣 west0479 的非零元素個數,其他類似的指令還有 nonzeros(傳回一個包含所有非零元素的行向量)及 nzmax(傳回最大的非零元素個數)。

Hint
  • 在一個稀疏矩陣中,將一個非零元素設定成零時,MATLAB 並不會自動釋放記憶體空間,換包話說,nnz 會隨著非零元素的減少而減少,但 nzmax 並不會隨著改變。但是當您多加一個非零元素時,若 nnz 已大於 nzmax 時,nzmax 會隨之增大(即 MATLAB 會自動配置記憶體)以儲存新加的元素。

上述的內存空間公式會隨著 MATLAB 的版本而有所改變,所以決定內存空間公式的最好方式是直接對 MATLAB 進行測試,範例如下:

Example 2: 05-稀疏矩陣/memorySize02.mcaseNum=100; A=zeros(caseNum, 4); % A in Ax=b b=zeros(caseNum, 1); % b in Ax=b for i=1:caseNum m=max([round(100*rand), 5]); n=max([round(100*rand), 5]); s=sprand(m, n, 0.1); sizeInfo=whos('s'); A(i,1)=nnz(s); A(i,2:3)=sizeInfo.size; A(i,4)=1; b(i)=sizeInfo.bytes; end x=A\b maxDiff=max(abs(A*x-b)) x = 16.0000 0.0000 8.0000 8.0000 maxDiff = 3.6380e-12

在上例中,我們事實上是在解一個線性方程式 Ax=b,其中我們使用了 100 個稀疏矩陣來產生 A,A 包含四個直行,每一個直行分別代表這 100 個稀疏矩陣的 nnz(非零元素個數)、m(橫列個數)、n(直行個數),以及常數 1,而 b 則是這幾個稀疏矩陣的內存空間大小。由上述範例所得到的預測誤差相當小,因此由 x 的值就可以知道每一個特徵(nnz、m、n)所佔用的內存空間分別是(16、0、8),而每一個稀疏矩陣還會用到 8 個位元組來儲存經常性資訊。

Hint
在上述範例中,我們使用「左除」(x=A\b)來使用最小平方法解聯立方程式,相關說明可見本書之「線性代數」章節。


MATLAB程式設計:進階篇